<template>
  <div class="main">
    <div class="watermark-container">
      <div class="header">
        <h1>Vue3 图片水印工具</h1>
        <p>上传图片并添加自定义文字或图片水印</p>
      </div>

      <div class="main-content">
        <div class="preview-section">
          <h2 class="section-title">预览</h2>
          <div class="preview-container" @click="triggerFileInput">
            <canvas ref="canvasRef" class="preview-canvas" v-show="imageLoaded"></canvas>
            <div class="upload-area" v-show="!imageLoaded">
              <div class="upload-icon">📁</div>
              <p>点击上传图片</p>
              <p class="upload-hint">支持 JPG、PNG 格式</p>
            </div>
          </div>
          <input
            type="file"
            ref="fileInput"
            @change="handleFileUpload"
            accept="image/*"
            style="display: none"
          />
          <div class="preview-actions">
            <button class="btn btn-primary" @click="applyWatermark" :disabled="!imageLoaded">
              应用水印
            </button>
            <button
              class="btn btn-secondary"
              @click="downloadImage"
              :disabled="!imageLoaded || !watermarkApplied"
            >
              下载图片
            </button>
            <button class="btn btn-outline" @click="resetAll" :disabled="!imageLoaded">重置</button>
          </div>
        </div>

        <div class="controls-section">
          <h2 class="section-title">水印设置</h2>

          <!-- 水印类型选择 -->
          <div class="control-group">
            <h3>水印类型</h3>
            <div class="control-row">
              <div class="control-item">
                <label class="radio-label">
                  <input type="radio" v-model="watermarkType" value="text" /> 文字水印
                </label>
              </div>
              <div class="control-item">
                <label class="radio-label">
                  <input type="radio" v-model="watermarkType" value="image" /> 图片水印
                </label>
              </div>
            </div>
          </div>

          <!-- 文字水印设置 -->
          <div class="control-group" v-if="watermarkType === 'text'">
            <h3>文字水印</h3>
            <div class="control-row">
              <div class="control-item">
                <label for="watermarkText">水印文字</label>
                <input
                  id="watermarkText"
                  type="text"
                  v-model="watermarkText"
                  placeholder="输入水印文字"
                />
              </div>
              <div class="control-item">
                <label for="watermarkColor">颜色</label>
                <input id="watermarkColor" type="color" v-model="watermarkColor" />
              </div>
            </div>

            <div class="control-row">
              <div class="control-item">
                <label for="fontSize">字体大小</label>
                <input id="fontSize" type="range" v-model="fontSize" min="12" max="72" />
                <span class="value-display">{{ fontSize }}px</span>
              </div>
              <div class="control-item">
                <label for="opacity">透明度</label>
                <input id="opacity" type="range" v-model="opacity" min="0.1" max="1" step="0.1" />
                <span class="value-display">{{ opacity }}</span>
              </div>
            </div>

            <div class="control-row">
              <div class="control-item">
                <label for="fontFamily">字体</label>
                <select id="fontFamily" v-model="fontFamily">
                  <option value="Arial">Arial</option>
                  <option value="Helvetica">Helvetica</option>
                  <option value="Times New Roman">Times New Roman</option>
                  <option value="Georgia">Georgia</option>
                  <option value="Courier New">Courier New</option>
                  <option value="Verdana">Verdana</option>
                </select>
              </div>
              <div class="control-item">
                <label for="fontWeight">字重</label>
                <select id="fontWeight" v-model="fontWeight">
                  <option value="normal">正常</option>
                  <option value="bold">粗体</option>
                  <option value="bolder">更粗</option>
                  <option value="lighter">更细</option>
                </select>
              </div>
            </div>
          </div>

          <!-- 图片水印设置 -->
          <div class="control-group" v-if="watermarkType === 'image'">
            <h3>图片水印</h3>
            <div class="control-row">
              <div class="control-item">
                <label>水印图片</label>
                <div class="image-upload-area" @click="triggerWatermarkInput">
                  <div v-if="!watermarkImage.src" class="upload-placeholder">
                    <div class="upload-icon">🖼️</div>
                    <p>点击上传水印图片</p>
                  </div>
                  <div v-else class="watermark-preview">
                    <img :src="watermarkImage.src" alt="水印预览" />
                    <button class="remove-btn" @click.stop="removeWatermarkImage">×</button>
                  </div>
                </div>
                <input
                  type="file"
                  ref="watermarkInput"
                  @change="handleWatermarkUpload"
                  accept="image/*"
                  style="display: none"
                />
              </div>
            </div>

            <div class="control-row">
              <div class="control-item">
                <label for="watermarkSize">水印大小</label>
                <input id="watermarkSize" type="range" v-model="watermarkSize" min="10" max="100" />
                <span class="value-display">{{ watermarkSize }}%</span>
              </div>
              <div class="control-item">
                <label for="imageOpacity">透明度</label>
                <input
                  id="imageOpacity"
                  type="range"
                  v-model="imageOpacity"
                  min="0.1"
                  max="1"
                  step="0.1"
                />
                <span class="value-display">{{ imageOpacity }}</span>
              </div>
            </div>
          </div>

          <!-- 通用设置 -->
          <div class="control-group">
            <h3>位置与样式</h3>
            <div class="control-row">
              <div class="control-item">
                <label for="position">位置</label>
                <select id="position" v-model="position">
                  <option value="center">居中</option>
                  <option value="top-left">左上</option>
                  <option value="top-right">右上</option>
                  <option value="bottom-left">左下</option>
                  <option value="bottom-right">右下</option>
                  <option value="custom">自定义</option>
                </select>
              </div>
              <div class="control-item">
                <label for="rotation">旋转角度</label>
                <input id="rotation" type="range" v-model="rotation" min="-180" max="180" />
                <span class="value-display">{{ rotation }}°</span>
              </div>
            </div>

            <!-- 自定义位置设置 -->
            <div class="control-row" v-if="position === 'custom'">
              <div class="control-item">
                <label for="customX">水平位置</label>
                <input id="customX" type="range" v-model="customX" min="0" max="100" />
                <span class="value-display">{{ customX }}%</span>
              </div>
              <div class="control-item">
                <label for="customY">垂直位置</label>
                <input id="customY" type="range" v-model="customY" min="0" max="100" />
                <span class="value-display">{{ customY }}%</span>
              </div>
            </div>

            <div class="control-row">
              <div class="control-item">
                <label> <input type="checkbox" v-model="repeatWatermark" /> 平铺水印 </label>
              </div>
              <div class="control-item">
                <label>
                  <input
                    type="checkbox"
                    v-model="addShadow"
                    :disabled="watermarkType === 'image'"
                  />
                  添加阴影
                </label>
              </div>
            </div>
          </div>

          <div class="control-group">
            <h3>预览选项</h3>
            <div class="control-row">
              <div class="control-item">
                <label> <input type="checkbox" v-model="autoApply" /> 自动应用更改 </label>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, watch, nextTick } from 'vue'

// 响应式数据
const fileInput = ref(null)
const watermarkInput = ref(null)
const canvasRef = ref(null)
const imageLoaded = ref(false)
const watermarkApplied = ref(false)

// 水印类型
const watermarkType = ref('text') // 'text' 或 'image'

// 文字水印设置
const watermarkText = ref('我的水印')
const watermarkColor = ref('#ffffff')
const fontSize = ref(24)
const opacity = ref(0.7)
const fontFamily = ref('Arial')
const fontWeight = ref('normal')

// 图片水印设置
const watermarkImage = reactive({
  src: null,
  width: 0,
  height: 0
})
const watermarkSize = ref(30)
const imageOpacity = ref(0.7)

// 通用设置
const position = ref('center')
const rotation = ref(0)
const repeatWatermark = ref(false)
const addShadow = ref(false)
const autoApply = ref(true)
const customX = ref(50)
const customY = ref(50)

const imageData = reactive({
  src: null,
  width: 0,
  height: 0
})

// 触发文件选择
const triggerFileInput = () => {
  fileInput.value.click()
}

// 触发水印图片选择
const triggerWatermarkInput = () => {
  watermarkInput.value.click()
}

// 处理主图片上传
const handleFileUpload = (event) => {
  const file = event.target.files[0]
  if (!file) return

  const reader = new FileReader()
  reader.onload = (e) => {
    const img = new Image()
    img.onload = () => {
      imageData.src = img
      imageData.width = img.width
      imageData.height = img.height
      imageLoaded.value = true

      nextTick(() => {
        drawImage()
        if (autoApply.value) {
          applyWatermark()
        }
      })
    }
    img.src = e.target.result
  }
  reader.readAsDataURL(file)
}

// 处理水印图片上传
const handleWatermarkUpload = (event) => {
  const file = event.target.files[0]
  if (!file) return

  const reader = new FileReader()
  reader.onload = (e) => {
    const img = new Image()
    img.onload = () => {
      watermarkImage.src = img
      watermarkImage.width = img.width
      watermarkImage.height = img.height

      if (autoApply.value && imageLoaded.value) {
        applyWatermark()
      }
    }
    img.src = e.target.result
  }
  reader.readAsDataURL(file)
}

// 移除水印图片
const removeWatermarkImage = () => {
  watermarkImage.src = null
  watermarkImage.width = 0
  watermarkImage.height = 0

  if (autoApply.value && imageLoaded.value) {
    applyWatermark()
  }
}

// 绘制原始图片到Canvas
const drawImage = () => {
  const canvas = canvasRef.value
  if (!canvas || !imageData.src) return

  const ctx = canvas.getContext('2d')

  // 设置Canvas尺寸与图片一致
  canvas.width = imageData.width
  canvas.height = imageData.height

  // 清除Canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height)

  // 绘制图片
  ctx.drawImage(imageData.src, 0, 0, canvas.width, canvas.height)
}

// 应用水印
const applyWatermark = () => {
  if (!imageLoaded.value) return

  drawImage() // 先绘制原始图片

  const canvas = canvasRef.value
  const ctx = canvas.getContext('2d')

  if (watermarkType.value === 'text') {
    applyTextWatermark(ctx, canvas.width, canvas.height)
  } else if (watermarkType.value === 'image' && watermarkImage.src) {
    applyImageWatermark(ctx, canvas.width, canvas.height)
  }

  watermarkApplied.value = true
}

// 应用文字水印
const applyTextWatermark = (ctx, width, height) => {
  // 设置水印样式
  ctx.font = `${fontWeight.value} ${fontSize.value}px ${fontFamily.value}`
  ctx.fillStyle = watermarkColor.value
  ctx.globalAlpha = opacity.value

  if (addShadow.value) {
    ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
    ctx.shadowBlur = 5
    ctx.shadowOffsetX = 2
    ctx.shadowOffsetY = 2
  }

  // 计算水印位置
  const { x, y } = calculatePosition(width, height)

  // 保存当前状态
  ctx.save()

  // 应用旋转
  ctx.translate(x, y)
  ctx.rotate((rotation.value * Math.PI) / 180)

  // 绘制水印
  if (repeatWatermark.value) {
    // 平铺水印逻辑
    drawRepeatedTextWatermark(ctx, width, height)
  } else {
    // 单个水印
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    ctx.fillText(watermarkText.value, 0, 0)
  }

  // 恢复状态
  ctx.restore()
}

// 应用图片水印
const applyImageWatermark = (ctx, width, height) => {
  // 计算水印尺寸
  const maxSize = Math.min(width, height) * (watermarkSize.value / 100)
  let watermarkWidth, watermarkHeight

  // 保持水印图片比例
  if (watermarkImage.width > watermarkImage.height) {
    watermarkWidth = maxSize
    watermarkHeight = (watermarkImage.height / watermarkImage.width) * maxSize
  } else {
    watermarkHeight = maxSize
    watermarkWidth = (watermarkImage.width / watermarkImage.height) * maxSize
  }

  // 计算水印位置
  const { x, y } = calculatePosition(width, height, watermarkWidth, watermarkHeight)

  // 保存当前状态
  ctx.save()

  // 设置透明度
  ctx.globalAlpha = imageOpacity.value

  // 应用旋转
  ctx.translate(x + watermarkWidth / 2, y + watermarkHeight / 2)
  ctx.rotate((rotation.value * Math.PI) / 180)

  // 绘制水印
  if (repeatWatermark.value) {
    // 平铺水印逻辑
    drawRepeatedImageWatermark(ctx, width, height, watermarkWidth, watermarkHeight)
  } else {
    // 单个水印
    ctx.drawImage(
      watermarkImage.src,
      -watermarkWidth / 2,
      -watermarkHeight / 2,
      watermarkWidth,
      watermarkHeight
    )
  }

  // 恢复状态
  ctx.restore()
}

// 计算水印位置
const calculatePosition = (width, height, watermarkWidth = 0, watermarkHeight = 0) => {
  let x, y

  switch (position.value) {
    case 'top-left':
      x = width * 0.05
      y = height * 0.05
      break
    case 'top-right':
      x = width * 0.95 - watermarkWidth
      y = height * 0.05
      break
    case 'bottom-left':
      x = width * 0.05
      y = height * 0.95 - watermarkHeight
      break
    case 'bottom-right':
      x = width * 0.95 - watermarkWidth
      y = height * 0.95 - watermarkHeight
      break
    case 'custom':
      x = (width - watermarkWidth) * (customX.value / 100)
      y = (height - watermarkHeight) * (customY.value / 100)
      break
    case 'center':
    default:
      x = (width - watermarkWidth) / 2
      y = (height - watermarkHeight) / 2
      break
  }

  return { x, y }
}

// 绘制平铺文字水印
const drawRepeatedTextWatermark = (ctx, width, height) => {
  const textWidth = ctx.measureText(watermarkText.value).width
  const textHeight = fontSize.value

  // 计算水印间距
  const spacingX = textWidth * 1.5
  const spacingY = textHeight * 2

  // 绘制网格水印
  for (let x = -width; x < width * 2; x += spacingX) {
    for (let y = -height; y < height * 2; y += spacingY) {
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText(watermarkText.value, x, y)
    }
  }
}

// 绘制平铺图片水印
const drawRepeatedImageWatermark = (ctx, width, height, watermarkWidth, watermarkHeight) => {
  // 计算水印间距
  const spacingX = watermarkWidth * 1.5
  const spacingY = watermarkHeight * 1.5

  // 绘制网格水印
  for (let x = -width; x < width * 2; x += spacingX) {
    for (let y = -height; y < height * 2; y += spacingY) {
      ctx.drawImage(
        watermarkImage.src,
        x - watermarkWidth / 2,
        y - watermarkHeight / 2,
        watermarkWidth,
        watermarkHeight
      )
    }
  }
}

// 下载图片
const downloadImage = () => {
  if (!watermarkApplied.value) return

  const canvas = canvasRef.value
  const link = document.createElement('a')
  link.download = `watermarked-image-${Date.now()}.png`
  link.href = canvas.toDataURL('image/png')
  link.click()
}

// 重置所有设置
const resetAll = () => {
  watermarkType.value = 'text'
  watermarkText.value = '我的水印'
  watermarkColor.value = '#ffffff'
  fontSize.value = 24
  opacity.value = 0.7
  fontFamily.value = 'Arial'
  fontWeight.value = 'normal'
  watermarkSize.value = 30
  imageOpacity.value = 0.7
  position.value = 'center'
  rotation.value = 0
  repeatWatermark.value = false
  addShadow.value = false
  customX.value = 50
  customY.value = 50

  removeWatermarkImage()

  if (imageLoaded.value) {
    drawImage()
    watermarkApplied.value = false
  }
}

// 监听水印参数变化，自动应用（如果启用）
watch(
  [
    watermarkType,
    watermarkText,
    watermarkColor,
    fontSize,
    opacity,
    fontFamily,
    fontWeight,
    watermarkSize,
    imageOpacity,
    position,
    rotation,
    repeatWatermark,
    addShadow,
    customX,
    customY
  ],
  () => {
    if (autoApply.value && imageLoaded.value) {
      applyWatermark()
    }
  },
  { deep: true }
)

// 监听水印图片变化
watch(
  () => watermarkImage.src,
  () => {
    if (autoApply.value && imageLoaded.value) {
      applyWatermark()
    }
  }
)
</script>

<style scoped>
.main {
  width: 100%;
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding-top: 50px;
}
.watermark-container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  background: white;
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.header {
  background: linear-gradient(90deg, #4b6cb7 0%, #182848 100%);
  color: white;
  padding: 20px;
  text-align: center;
}

.header h1 {
  font-size: 28px;
  margin-bottom: 10px;
}

.header p {
  opacity: 0.8;
}

.main-content {
  display: flex;
  flex-wrap: wrap;
  padding: 20px;
  gap: 20px;
}

.preview-section,
.controls-section {
  flex: 1;
  min-width: 300px;
}

.section-title {
  font-size: 18px;
  margin-bottom: 15px;
  color: #2c3e50;
  border-bottom: 2px solid #eee;
  padding-bottom: 8px;
}

.preview-container {
  border: 2px dashed #ddd;
  border-radius: 8px;
  height: 400px;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  background: #f9f9f9;
  margin-bottom: 20px;
  cursor: pointer;
  transition: border-color 0.3s;
}

.preview-container:hover {
  border-color: #4b6cb7;
}

.preview-canvas {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.upload-area {
  text-align: center;
  padding: 40px 20px;
  color: #7f8c8d;
}

.upload-icon {
  font-size: 48px;
  margin-bottom: 15px;
}

.upload-hint {
  font-size: 14px;
  margin-top: 5px;
}

.preview-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}

.btn {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.3s;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn-primary {
  background: #4b6cb7;
  color: white;
}

.btn-primary:hover:not(:disabled) {
  background: #3a5599;
}

.btn-secondary {
  background: #27ae60;
  color: white;
}

.btn-secondary:hover:not(:disabled) {
  background: #219653;
}

.btn-outline {
  background: transparent;
  border: 1px solid #ddd;
  color: #7f8c8d;
}

.btn-outline:hover:not(:disabled) {
  background: #f5f5f5;
}

.control-group {
  margin-bottom: 20px;
  background: #f8f9fa;
  padding: 15px;
  border-radius: 8px;
}

.control-group h3 {
  margin-bottom: 15px;
  color: #34495e;
  font-size: 16px;
}

.control-row {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  margin-bottom: 15px;
}

.control-item {
  flex: 1;
  min-width: 120px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
  color: #34495e;
}

.radio-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.radio-label input {
  width: auto;
}

input,
select {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 14px;
}

input[type='color'] {
  height: 40px;
  padding: 3px;
}

input[type='range'] {
  padding: 0;
}

.value-display {
  display: inline-block;
  margin-left: 10px;
  font-size: 14px;
  color: #7f8c8d;
}

.image-upload-area {
  border: 2px dashed #ddd;
  border-radius: 6px;
  padding: 15px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-upload-area:hover {
  border-color: #4b6cb7;
}

.upload-placeholder {
  color: #7f8c8d;
}

.watermark-preview {
  position: relative;
  max-width: 100%;
  max-height: 100px;
}

.watermark-preview img {
  max-width: 100%;
  max-height: 100px;
  object-fit: contain;
}

.remove-btn {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 24px;
  height: 24px;
  background: #e74c3c;
  color: white;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
}

.footer {
  background: #f8f9fa;
  padding: 15px;
  text-align: center;
  color: #7f8c8d;
  font-size: 14px;
}

@media (max-width: 768px) {
  .main-content {
    flex-direction: column;
  }

  .preview-section,
  .controls-section {
    width: 100%;
  }
}
</style>